package com.mygdx.game.desktop.demo;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;

/**
 * .物理引擎 Box2d中，物体可以接受力（Force）、冲量（Impulse）和扭矩（Torque）。
 * -这些物理元素都能改变物体的运动形式，并且默认都会唤醒物体，当然只是针对动态物体。
 * 
 * @author Administrator
 *
 */
public class PhysicsEngineTestGame extends Game {

	World world;
	OrthographicCamera camera;
	Box2DDebugRenderer debugRenderer;
	ShapeRenderer rend;
	// 一个数组，用于放置当前模拟中的所有实体
	private final Array<Body> arrBody = new Array<Body>();
	private Texture ballsTexture;
	private TextureRegion ballRegion;
	private SpriteBatch batch;
	private Sprite sprite;

	@Override
	public void create() {

		/**
		 * new Vector2(0, -10)世界中的重力系统,第一个是x水平方向的，第二个是y值垂直方向的。
		 * true指的是对象是否可以睡眠。其实也就是文档中介绍的让某些物理世界中的物体睡眠以节约cpu资源。
		 */
		world = new World(new Vector2(0, -10), true);

		debugRenderer = new Box2DDebugRenderer();

		camera = new OrthographicCamera();
		camera.setToOrtho(false, Gdx.graphics.getWidth() / 10, Gdx.graphics.getHeight() / 10);

		ballsTexture = new Texture(Gdx.files.internal("images/ball.png"));
		ballRegion = new TextureRegion(ballsTexture, 0, 0, ballsTexture.getWidth() / 4, ballsTexture.getHeight());

		batch = new SpriteBatch();
		sprite = new Sprite(ballRegion);
		sprite.setSize(4, 4);
		// create the body of box
		BodyDef boxBodyDef = new BodyDef();
		boxBodyDef.type = BodyType.DynamicBody;
		// boxBodyDef.position.x = -24 + (float)(Math.random() * 48);
		// boxBodyDef.position.y = 10 + (float)(Math.random() * 100);
		boxBodyDef.position.set(40, 50);
		Body boxBody = world.createBody(boxBodyDef);
		PolygonShape boxPoly = new PolygonShape();
		boxPoly.setAsBox(2, 1);
		boxBody.createFixture(boxPoly, 1);
		boxPoly.dispose();

		// create the body of circle
		BodyDef bodyDef = new BodyDef();
		bodyDef.type = BodyType.DynamicBody;
		bodyDef.position.set(60, 100);
		Body bodyCircle = world.createBody(bodyDef);
		CircleShape circle = new CircleShape();
		circle.setRadius(2);
		/*FixtureDef fixtureDef = new FixtureDef();
		fixtureDef.shape = circle;
		fixtureDef.density = 1f;
		fixtureDef.friction = 0.4f;
		// fixtureDef.restitution = 0.6f;
		bodyCircle.createFixture(fixtureDef);*/
		bodyCircle.createFixture(circle, 1);
		bodyCircle.setUserData(sprite);
		circle.dispose();

		// 静态body作为地面
		BodyDef groundBodyDef = new BodyDef();
		groundBodyDef.type = BodyType.StaticBody;
		groundBodyDef.angle = (float) Math.PI * 15 / 180;
		groundBodyDef.position.set(0, 0);
		Body groundBody = world.createBody(groundBodyDef);
		PolygonShape groundBox = new PolygonShape();
		groundBox.setAsBox(camera.viewportWidth + 5, 0.5f);
		groundBody.createFixture(groundBox, 0.0f);
		groundBox.dispose();
		// 静态body作为地面2
		BodyDef groundBodyDef2 = new BodyDef();
		groundBodyDef2.type = BodyType.StaticBody;
		groundBodyDef2.angle = (float) Math.PI * 165 / 180;
		groundBodyDef2.position.set(30, 0);
		Body groundBody2 = world.createBody(groundBodyDef2);
		PolygonShape groundBox2 = new PolygonShape();
		groundBox2.setAsBox(camera.viewportWidth + 5, 0.5f);
		groundBody2.createFixture(groundBox2, 0.0f);
		groundBox2.dispose();
	}

	public void render() {
		super.render();
		Gdx.gl.glClearColor(1, 1, 1, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		world.step(Gdx.graphics.getDeltaTime(), 6, 2);
		camera.update();
		debugRenderer.render(world, camera.combined);

		// 设置此批处理使用的投影矩阵
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		world.getBodies(arrBody);
		for (int i = 0; i < arrBody.size; ++i) {
			Body body = arrBody.get(i);
			Sprite sp = (Sprite) body.getUserData();
			if (sp != null) {
				sp.setPosition(body.getPosition().x - 2, body.getPosition().y - 2);
				sp.setCenter(body.getPosition().x, body.getPosition().y);
				//sp.setRotation(MathUtils.radiansToDegrees * body.getAngle());
				//System.out.println(body.getAngle()+","+MathUtils.radiansToDegrees * body.getAngle());
				sp.draw(batch);
			}
		}
		batch.end();

	}

	public void dispose() {
		debugRenderer.dispose();
		world.dispose();
		super.dispose();
	}

	public static void main(String[] args) {
		new LwjglApplication(new PhysicsEngineTestGame());
	}
}
